﻿using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using Foothill.IoC;
using Foothill.Model;
using Foothill.Service.UserAccount;

namespace Foothill.Web.AccountRegistration
{
    public partial class AccountRegistration : FoothillBasePage
    {
        private IAccountRegistrationManager _accountRegistrationManager;

        // field and the corresponding error message label
        protected IDictionary<UserAccountField, Label> _fieldToLabel; 
        
        protected void Page_Load(object sender, EventArgs e)
        {
            _accountRegistrationManager = IocContainer.GetInstance<IAccountRegistrationManager>();

            _fieldToLabel = new Dictionary<UserAccountField, Label>
            {
                { UserAccountField.Email, lblEmailErrorMessage },
                { UserAccountField.Username, lblUsernameErrorMessage },
                { UserAccountField.Password, lblPasswordErrorMessage },
                { UserAccountField.ConfirmPassword, lblConfirmPwdErrorMessage }
            };

            HideAllMessageTexts();
        }

        private void HideAllMessageTexts()
        {
            lblEmailErrorMessage.Visible = false;
            lblUsernameErrorMessage.Visible = false;
            lblPasswordErrorMessage.Visible = false;
            lblConfirmPwdErrorMessage.Visible = false;
            lblCreateAccountMessage.Visible = false;
        }

        protected void btnCreateAccountClick(object sender, EventArgs e)
        {
            AccountRegistrationInfo registrationInfo = new AccountRegistrationInfo();

            registrationInfo.Email = txtEmail.Text;
            registrationInfo.Username = txtUsername.Text;
            registrationInfo.Password = txtPassword.Text;
            registrationInfo.ConfirmPassword = txtConfirmPwd.Text;

            ICollection<Tuple<UserAccountField, string>> invalidFieldsAndError = new List<Tuple<UserAccountField, string>>();
            ValidateAccountRegistrationResult validateResult = _accountRegistrationManager.ValidateAccountRegistrationInfo(registrationInfo, invalidFieldsAndError);

            if (validateResult == ValidateAccountRegistrationResult.OkToCreateNewAccount)
            {
                // user inputs validated, create new account in db
                try
                {
                    _accountRegistrationManager.CreateNewAccount(registrationInfo);
                    Response.Redirect("~/AccountRegistration/RegistrationComplete.aspx");
                }
                catch (FailToCreateAccountException ex)
                {
                    // display error, error is stored in the Message field of the exception thrown
                    lblCreateAccountMessage.Visible = true;
                    lblCreateAccountMessage.Text = ex.Message;
                }
            }
            else if (validateResult == ValidateAccountRegistrationResult.SendAnotherActivation)
            {
                try
                {
                    _accountRegistrationManager.SendAnotherActivation(registrationInfo);
                    Response.Redirect("~/AccountRegistration/RegistrationComplete.aspx");
                }
                catch (FailToCreateAccountException ex)
                {
                    // display error, error is stored in the Message field of the exception thrown
                    lblCreateAccountMessage.Visible = true;
                    lblCreateAccountMessage.Text = ex.Message;
                }
            }
            else
            {
                // display validation error message
                DisplayValidationError(invalidFieldsAndError);
            }
        }

        private void DisplayValidationError(ICollection<Tuple<UserAccountField, string>> invalidFieldsAndError)
        {
            foreach (Tuple<UserAccountField, string> tuple in invalidFieldsAndError)
            {
                // get the corresponding label and display the error
                Label errorMessageLabel;
                if (_fieldToLabel.TryGetValue(tuple.Item1, out errorMessageLabel))
                {
                    errorMessageLabel.Text = tuple.Item2;
                    errorMessageLabel.Visible = true;
                }
            }
        }
    }
}